package com.rtf.framework.common.util;

import com.rtf.framework.common.exception.AppException;
import lombok.Getter;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.codec.binary.Hex;
import javax.crypto.Cipher;
import javax.crypto.spec.SecretKeySpec;
import java.io.Serializable;

/**
 *
 * AES加密解密
 *
 * @author liuke
 * @date  2021/7/28 15:00
 * @version
*/
@Slf4j
public class UtilAESCrypto {

    private final static String DEFAULT_KEY="uS4HXVAQ8QTBmdzb";

    /**
     *加密算法需要传入16位key
     *
     * @param str
     * @param key
     * @author liuke
     * @date 2021/7/2 8:49
     * @return java.lang.String
     */
    public static String encrypt(String str, String key) {
        //判断加密字符串是否为空
        if(UtilString.isBlank(str)){
            throw new AppException("加密字符串不能为空");
        }
        //如果key大于16位，截取前16位作为秘钥
        if(UtilString.isNotBlank(key) && key.length() > 16){
            key = key.substring(0,16);
        }
        // 如果key为空或者长度不是16位取默认key
        else if (UtilString.isBlank(key) || key.length() < 16) {
            key = DEFAULT_KEY;
        }

        try {
            byte[] raw = key.getBytes("utf-8");
            SecretKeySpec skeySpec = new SecretKeySpec(raw, "AES");
            //"算法/模式/补码方式"
            Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
            cipher.init(Cipher.ENCRYPT_MODE, skeySpec);
            byte[] encrypted = cipher.doFinal(str.getBytes("utf-8"));

            return Hex.encodeHexString(encrypted);

        } catch (Exception e) {
            log.error("{}加密失败,原因:{}", str, e.getMessage());
            throw new AppException("加密失败" + e.getMessage());
        }
    }

    /**
     *解密算法需要传16位key
     *
     * @param str
     * @param key
     * @author liuke
     * @date 2021/7/2 8:50
     * @return java.lang.String
     */
    public static String decrypt(String str, String key) {
        try {
            //判断解密字符串是否为空
            if(UtilString.isBlank(str)){
                throw new AppException("解密字符串不能为空");
            }
            //如果key大于16位，截取前16位作为秘钥
            if(UtilString.isNotBlank(key) && key.length() > 16 ){
                key = key.substring(0,16);
            }
            // 如果key为空或者长度不是16位取默认key
            else if (UtilString.isBlank(key) || key.length() < 16) {
                key = DEFAULT_KEY;
            }
            byte[] raw = key.getBytes("utf-8");
            SecretKeySpec skeySpec = new SecretKeySpec(raw, "AES");
            Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
            cipher.init(Cipher.DECRYPT_MODE, skeySpec);
            //先用Hex解码
            byte[] encrypted1 = Hex.decodeHex(str);
            byte[] original = cipher.doFinal(encrypted1);
            String originalString = new String(original, "utf-8");
            return originalString;
        } catch (Exception e) {
            log.error("{}解密失败,原因:{}", str, e.getMessage());
            throw new AppException("解密失败" + e.getMessage());
        }
    }

    /**
     *加密算法使用默认key
     *
     * @param str
     * @author liuke
     * @date 2021/7/2 8:55
     * @return java.lang.String
     */
    public static String encrypt(String str){
        return encrypt(str,DEFAULT_KEY);
    }


    /**
     *解密算法使用默认key
     *
     * @param str
     * @author liuke
     * @date 2021/7/2 8:56
     * @return java.lang.String
     */
    public static String decrypt(String str) throws Exception{
        return decrypt(str,DEFAULT_KEY);
    }

    /**
     * sessionID加密处理
     * @param  userId
     * @param time
     * @param ranDomNum
     * @param  serverName
     * @param  version
     * @return
     */
    public static String encryptSessionId(String userId, Long time, String ranDomNum, String serverName, String version){
        StringBuffer sb = new StringBuffer();
        sb.append(serverName);
        sb.append("@-@");
        sb.append(ranDomNum);
        sb.append("@-@");
        sb.append(time);
        sb.append("@-@");
        sb.append(userId);
        sb.append("@-@");
        sb.append(version);
        return encrypt(sb.toString());
    }

    /**
     *
     * @param userId
     * @param time
     * @param serverName
     * @param version
     * @return
     */
    public static String encryptSessionId(String userId, Long time, String serverName, String version){
        return encryptSessionId(userId,time,UtilRandomNum.generateNumber(6),serverName,version);
    }

    /**
     *sessionId解密处理
     *
     * @param sessionId
     * @author liuke
     * @date 2021/7/2 11:28
     * @return java.lang.String
     */
    public static SessionValue decryptSessionId(String sessionId) throws Exception{
        //根据逗号截取字符串数组
        String[] str1 = decrypt(sessionId).split("@-@");
        //构建对象
        SessionValue sessionValue = new SessionValue(str1[0],str1[2],str1[3],str1[4]);
        return sessionValue;
    }


    @Getter
    public static class SessionValue implements Serializable{

        public SessionValue(String serverName,String time,String userId,String version){
            this.serverName = serverName;
            this.time = Long.valueOf(time);
            this.userId=userId;
            this.version=version;
        }
        private String serverName;
        private Long time;
        private String userId;
        private String version;
    }


}
